/*!
 * Copyright (C) 2020 - All Rights Reserved by
 * @author : ZhaoYanbo
 * @email  : zyb920@hotmail.com
 * @created: 2020-10-31
 * @version: 1.0.0.0
 *
 */

#ifndef LYRICEDITWIDGET_H
#define LYRICEDITWIDGET_H

#include <QWidget>
#include <QPixmap>
#include "LyricEditData.h"
#include "le_command.h"
#include "le_ruler.h"

//歌词编辑器界面
class LyricEditWidget final : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(FineShowMode showMode READ showMode WRITE setShowMode)
    Q_PROPERTY(QString  showString READ showString WRITE setShowString)
public:
    explicit LyricEditWidget(QWidget *parent = nullptr);
    ~LyricEditWidget() override;

    void setLineHeight(int h) {
        m_lineHeight = h;
        update();
    }

    void setShowMode(FineShowMode mode);
    FineShowMode showMode() const{
        return m_showMode;
    }

    void setShowString(const QString &str);
    QString showString() const {
        return m_origiStr;
    }

    bool pressed() const { return m_pressed; }
    ///开启伸缩时 缩放操作 默认关闭
    void openScaleMode(bool b = true);

    bool loadFromValues(const QVector<VPos> &points);
    bool loadFromPoints(const QVector<ZPos> &points);

    void undo() { p_invoker->undo(); }
    void redo() { p_invoker->redo(); }
    bool canUndo() const { return p_invoker->canUndo(); }
    bool canRedo() const { return p_invoker->canRedo(); }

    //外部接口专用
    void zoomIn();
    void zoomOut();
    bool canZoomIn()  const { return p_ruler->canZoomIn(); }
    bool canZoomOut() const { return p_ruler->canZoomOut(); }
    //命令模式专用
    void zoomInCommand();
    void zoomOutCommand();

    bool canMove(int index) const;
    bool invertPreview(int index);

    ///处理点击move线
    bool doClickCanMove(int index);
    ///处理点击preview
    bool doClickPreview(int index);

    void updateSize(int w = -1);

    QVector<VPos> points2values(const QVector<ZPos> &points) const;

private:
    ///
    /// \brief 检查pos是否在竖线上 或者 区域内部
    /// \param pos: 当前坐标
    /// \return -1: 区域外  -2:区域内  >=0:index
    ///
    int checkCursor(const QPoint &pos) const;

    ///检查是否点击can move区域
    int doClickMoveRect(const QPoint &pos) const;
    ///检查是否点击preview区域
    int doClickPreview(const QPoint &pos) const;

    ///矩形框坐标大小
    QRect canMoveRect(const ZPos &pos) const;
    ///preview坐标大小
    QRect previewRect(const ZPos &pos) const;

    ///处理鼠标没有按下时移动
    bool doHoverMove(const QPoint &pos);

    ///处理鼠标按下时移动
    bool doMouseMove(int x);
    ///处理鼠标按下
    bool doMousePress(const QPoint &pos);

    ///判断索引是否在有效范围
    bool isValid(int index) const;

    void updateRuler();

protected:
    void paintEvent(QPaintEvent *) override;
    void mousePressEvent(QMouseEvent *e) override;
    void mouseMoveEvent(QMouseEvent *e) override;
    void mouseReleaseEvent(QMouseEvent *e) override;
    void resizeEvent(QResizeEvent *e) override;

private:
    bool m_pressed;         //是否按下
    bool m_scaleMode;       //是否开启伸缩时缩放
    int  m_lineHeight;      //默认线高度
    int  m_selectedIndex;   //标记按下的竖线索引
    int  m_curX;            //当前时间线X
    int  m_sy;              //起始点Y值
    int  m_prePreviewIndex; //上一个preview的索引(用于undo)
    FineShowMode m_showMode;//显示模式

    QString m_origiStr;     //原始字符串
    QString m_str;          //处理后的字符串(去除空格)

    QPoint m_pressedPos;    //按下坐标

    QVector<ZPos> m_linePos;//绘制线
    QVector<ZPos> m_origiLinePos;//纪录按下之前的原始线
    QVector<VPos> m_origiLineValus;//纪录按下之前的原始值(标尺变化后 坐标对了 值不对)

    QPixmap m_markPic;      //刻度图

    LE_Ruler *p_ruler = nullptr;
    LE_CommandInvok *p_invoker = nullptr;
};

#endif // LYRICEDITWIDGET_H
